package cn.topevery.garden.dal.logic;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.topevery.garden.dal.constant.StringConstant;
import cn.topevery.garden.dal.dao.ProjPlanDao;
import cn.topevery.garden.entity.dto.ProjPlanCudDTO;
import cn.topevery.garden.entity.dto.ProjPlanDTO;
import cn.topevery.garden.entity.po.*;
import cn.topevery.garden.entity.query.ProjPlanQuery;
import cn.topevery.garden.entity.vo.*;

import cn.topevery.garden.framework.Database;
import cn.topevery.garden.framework.base.BaseLogic;
import hw.topevery.framework.db.entity.DataPager;
import hw.topevery.framework.db.base.BaseEntityDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 项目计划表
 *
 * @author code-generate
 * @date 2022-11-02
 */
@Service
public class ProjPlanLogic extends BaseLogic<ProjPlan> {
    @Autowired
    ProjPlanDao projPlanDao;

    @Autowired
    ProjBasicInfoLogic projBasicInfoLogic;

    @Autowired
    ProjContractLogic projContractLogic;

    @Autowired
    ProjFilesLogic projFilesLogic;

    @Override
    public BaseEntityDao<ProjPlan, Integer> getDao() {
        return projPlanDao;
    }

    

    /**
     * 获取列表
     *
     * @param query
     */
    public DataPager<ProjPlanVO> listPage(ProjPlanQuery query) {
        return projPlanDao.listPage(query);
    }

    public List<ProjPlanAndProjNameVO> list(ProjPlanQuery query) {
        List<ProjPlanAndProjNameVO> list = projPlanDao.list(query);
        // 当传入的项目ID不为空时，查询标段附件信息
        if (ObjectUtil.isNotEmpty(query.getProjId())) {
            if (CollUtil.isNotEmpty(list)) {
                // 获取项目及招标文件
                List<ProjFilesVO> filesList = projFilesLogic.listByProjIdAndStageTypeCode(query.getProjId(), StringConstant.ProjStageFileCode.ProjPlan);
                if (CollUtil.isNotEmpty(filesList)) {
                    for (ProjPlanAndProjNameVO projPlanVO : list) {
                        List<ProjFilesVO> projPlanFilesVOs = filesList.stream().filter(files -> ObjectUtil.isNotEmpty(files.getProjStageId()) && files.getProjStageId().equals(projPlanVO.getPlanId())).collect(Collectors.toList());
                        projPlanVO.setFiles(projPlanFilesVOs);
                    }
                }
            }
        }
        return list;
    }

    public List<ProjPlanIndexVO> listByProjId(String projId) {
        return this.projPlanDao.listByProjId(projId);
    }
    /**
     * 根据自增id批量删除
     *
     * @param ids
     */
    @Transactional
    public void deleteBatchById(String userId,Integer[] ids) {
        // 根据ID查询招标信息
        ProjPlanQuery query = new ProjPlanQuery();
        query.setIds(ids);
        List<ProjPlanAndProjNameVO> planList = this.projPlanDao.list(query);
        if (CollUtil.isEmpty(planList)) {
            return;
        }
        List<String> planIds = planList.stream().map(bidVO -> bidVO.getPlanId()).collect(Collectors.toList());


        projPlanDao.delete(userId, ids);

        // 删除对应附件
        projFilesLogic.updateFilesByProjStageIds(planIds, null, userId);
    }

    /**
     * 批量保存、修改、删除接口
     * @param userId
     * @param cudDto
     * @return
     */
    public boolean saveOrUpdateOrDelete(String userId, ProjPlanCudDTO cudDto) {
        if (ObjectUtil.isEmpty(cudDto)) {
            throw new RuntimeException("传入的集合不能为空！");
        }
        Database.transactionScope(() -> {
            List<ProjPlanDTO> planDTOList = cudDto.getSaveAndUpdateProjPlanList();
            if (CollUtil.isNotEmpty(planDTOList)) {
                this.saveOrUpdate(userId, planDTOList);
            }
            Integer[] deleteIds = cudDto.getDeleteIds();
            if (ObjectUtil.isNotEmpty(deleteIds)) {
                this.deleteBatchById(userId, deleteIds);
            }
        });
        return true;
    }

    @Transactional
    public boolean saveOrUpdate(String userId, List<ProjPlanDTO> dtoList) {
        if (CollUtil.isEmpty(dtoList)) {
            throw new RuntimeException("传入的集合不能为空！");
        }

        // 校验标段数据
        for (ProjPlanDTO dto : dtoList) {
            this.checkProjPlanData(dto);
        }

        Database.transactionScope(() -> {
            for (ProjPlanDTO dto : dtoList) {
                ProjPlan projPlan = new ProjPlan();
                BeanUtil.copyProperties(dto, projPlan);

                // 保存数据
                this.projPlanDao.saveOrUpdate(userId, projPlan);

                //  保存附件
                if (ObjectUtil.isNotEmpty(dto.getFiles())) {
                    List<ProjFiles> files = dto.getFiles().stream().filter(i -> ObjectUtil.isEmpty(i.getId())).collect(Collectors.toList());
                    files.stream().forEach(i -> {
                        i.setProjId(dto.getProjId());
                        i.setProjStageId(projPlan.getPlanId()); // 计划ID
                    });
                    if (CollUtil.isNotEmpty(files)) {
                        projFilesLogic.insert(userId, files);
                    }
                }
                //  删除附件
                if (ObjectUtil.isNotEmpty(dto.getDeleteFileIds())) {
                    projFilesLogic.delete(userId, dto.getDeleteFileIds());
                }
            }
        });

        return true;
    }

    private void checkProjPlanData(ProjPlanDTO dto) {
        if (ObjectUtil.isEmpty(dto)) {
            throw new RuntimeException("传入的对象不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getProjId())) {
            throw new RuntimeException("项目ID不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getPlanCode())) {
            throw new RuntimeException("计划编码不能为空！");
        }
        // todo 校验计划编码是否存在，取字典

        if (ObjectUtil.isEmpty(dto.getPlanName())) {
            throw new RuntimeException("计划名称不能为空！");
        }
        // 当不为空时为修改
        if (ObjectUtil.isNotEmpty(dto.getPlanId())) {
            // 根据项目计划ID查询信息的有效性
            ProjPlanVO projPlan = this.getEntityById(dto.getPlanId());
            if (ObjectUtil.isEmpty(projPlan)) {
                throw new RuntimeException("该项目计划信息在系统不存在，请检查或刷新数据！");
            }
            dto.setId(projPlan.getId());
        } else {
            dto.setPlanId(UUID.randomUUID().toString());
        }

        // 检查项目ID
        ProjBasicInfo projBasicInfo = projBasicInfoLogic.getByProjId(dto.getProjId());
        if (ObjectUtil.isEmpty(projBasicInfo)) {
            throw new RuntimeException("该项目不存在，请检查!");
        }

        // 检查合同id
        if (ObjectUtil.isNotEmpty(dto.getContractId())) {
            ProjContract projContract = projContractLogic.getEntityByGuidId(dto.getContractId());
            if (ObjectUtil.isEmpty(projContract)) {
                throw new RuntimeException("该合同不存在，请刷新或检查!");
            }
            if (projContract.getDbStatus()) {
                throw new RuntimeException("该合同无效，请刷新或检查!");
            }
        }

        // 校验附件信息
        this.checkFiles(dto.getFiles(), dto.getPlanId(), dto.getProjId());

    }

    public ProjPlanVO getEntityById(String planId) {
        if (ObjectUtil.isEmpty(planId)) {
            throw new RuntimeException("传入的计划ID不能为空");
        }
        return this.projPlanDao.getEntityById(planId);
    }

    public ProjPlanAndFilesVO getDetailAndFileByGuid(String planId) {
        if (ObjectUtil.isEmpty(planId)) {
            throw new RuntimeException("传入的计划ID不能为空");
        }
        ProjPlanAndFilesVO projPlanAndFilesVO = new ProjPlanAndFilesVO();
        ProjPlanVO projPlanVO = this.projPlanDao.getEntityById(planId);
        BeanUtil.copyProperties(projPlanVO, projPlanAndFilesVO);

        // 查询项目信息
        if (ObjectUtil.isNotEmpty(projPlanVO) && ObjectUtil.isNotEmpty(projPlanVO.getProjId())) {
            ProjBasicInfo projBasicInfo = this.projBasicInfoLogic.getByProjId(projPlanVO.getProjId());
            projPlanAndFilesVO.setProjBasicInfo(projBasicInfo);
        }

        // 查询附件信息
        List<ProjFilesVO> baseInfoFiles = projFilesLogic.listByProjIdAndStageId(projPlanVO.getProjId(), projPlanVO.getPlanId());
        projPlanAndFilesVO.setFiles(baseInfoFiles);

        return projPlanAndFilesVO;
    }

    private void checkFiles(List<ProjFiles> files, String planId, String projId) {
        if (CollUtil.isEmpty(files)) {
            return;
        }
        for(ProjFiles file : files) {
            if (ObjectUtil.isEmpty(file.getFileId())) {
                throw new RuntimeException("传入的附件ID不能为空！");
            }
            file.setProjStageId(planId);
            file.setProjId(projId);
        }
    }
}
